<template>

	<view class="uni-flex uni-row">
		<view class="uni-flex uni-column menu" style="width: 200px;">
			<view class="text">图片尺寸</view>
			<view class="text">宽:{{ imageWidth }}px 高:{{ imageHeight }}px</view>
			<button type="primary" @click="chooseImage">选择图片</button>
			<!-- <button type="default" @click="onTestAPI">测试按钮</button> -->
			<view class="text">工具</view>
			<view class="uni-flex uni-row">
				<button type="default" @click="setPenStrokeConfirm" :style="strokeBtnStyle">涂抹</button>
				<button type="default" @click="setPenStrokeCancel" :style="eraseBtnStyle">橡皮</button>
				<button type="default" @click="onClearTrace">重置</button>
			</view>
			<view class="text">回撤/重做</view>
			<view class="uni-flex uni-row">
				<button class="uni-icon" type="default" @click="undoDraw">
					<uni-icons type="undo-filled" size="30"></uni-icons>
				</button>
				<button class="uni-icon" type="default" @click="redoDraw">
					<uni-icons type="redo-filled" size="30"></uni-icons>
				</button>
			</view>
			<view class="text">画笔大小（ALT+滚轮）</view>
			<view>
				<slider :value="lineWidth" @change="lineWidthChange" :min="minLineWidth" :max="maxLineWidth"
					show-value />
			</view>
			<view class="uni-flex uni-row">
				<button type="default" @click="retouche">智能修图</button>
				<button type="default" @click="recovery" :disabled="recoveryDisabled">主体还原</button>
			</view>
			<button type="default" @click="download">下载图片</button>
			<button type="default" @click="downloadMarker">下载蒙层</button>
			<view class="text">画板大小</view>
			<view>
				<slider :value="scale * 100" @change="scaleChange" min="10" max="150" show-value step="10" />
			</view>
		</view>
		<view id="canvas-container" class="uni-flex uni-row" :style="containerStyle">
			<!-- <canvas canvas-id="canvas" id="canvas" class="canvas" :style="canvasStyle"
			@touchstart="ontouchstart" @touchmove="ontouchmove" @touchend="ontouchend"
			@mousedown="ontouchstart" @mousemove="ontouchmove" @mouseup="ontouchend"></canvas> -->
			<canvas canvas-id="cursor" id="cursor" class="cursor" :style="cursorStyle"></canvas>
			<canvas canvas-id="marker" id="marker" class="marker" :style="canvasStyle"></canvas>
			<canvas canvas-id="board" id="board" class="board" :style="canvasStyle"></canvas>
			<canvas canvas-id="canvas" id="canvas" class="canvas" :style="canvasStyle"></canvas>
			<canvas canvas-id="temp" id="temp" class="canvas" :style="canvasStyle" v-show="showTemp"></canvas>
		</view>
	</view>
</template>


<script>
// 压缩判断 按照质量压缩，4M以内 done  压缩比例太大  10M会变成500K左右
// 1. 撤回功能， 支持前撤和后撤
// done 用ponits替代image的重画效果
// 2. 能不能在智能修图按钮的旁边，加一个按钮：主体还原。 done
// url：POST /image/main_body_recovery.json
// 参数：origin_image，原图的base64；process_image，智能修图后的图片的base64
// 返回值：target_image，最新的图片base64
// 需要保存最初的图片
// 3. 第一笔出现黑线的情况与点击生成原点相应出现，第一笔出现黑线的情况偶发，需要第一张图片完全加载完 不会出现此情况
// fix: tempCanvas 显示的问题，设置完canvas width和height再隐藏
// 4. 滚轮支持画笔的大小变化 done


// BUG
// 1. 画笔太快会导致canvas崩掉，后续画笔无法生效，drawImage失效（可能image大小问题，也可能是延迟问题）


import circleImg from '/static/circle.png';
import { throttle, generateUUID, base64ToFile, base64ClipPrefix, base64ToImageFile, base64ToBlob } from '../../../common/util';
import localForage from 'localForage';
import { Trace } from './tools';

let DrawTrace = new Trace();
let ctx = null;
let tempCtx = null;

export default {
	data() {
		return {
			containerStyle: {
				position: 'relative',
				width: '100%',
				height: 'calc(100vh - 120px)',
				flex: '1',
				backgroundColor: '#ddd',
				overflow: 'auto',
				// touchAction: 'none',
				// cursor: 'url() 11 11, auto'
			},
			canvasStyle: {
				width: '5px',
				height: '5px',
				transform: "translate(-50%, -50%) scale(1)"
			},
			cursorStyle: {
				width: '110px',
				height: '110px',
			},
			strokeBtnStyle: {
				color: '',
				border: '',
				// color: this.activePen === 'stroke' ? '#007aff' : ''
			},
			eraseBtnStyle: {
				color: '',
				border: '',
				// color: this.activePen === 'erase' ? '#007aff' : ''
			},
			imageWidth: '',
			imageHeight: '',
			pointGroup: [],
			mouseButtonDown: false,
			rect: null,
			ctx: null,
			board: null,
			marker: null,
			cursor: null,
			temp: null,
			scale: 1,
			lineWidth: 25,
			minLineWidth: 1,
			maxLineWidth: 100,
			imageMaxSize: 4 * 1024 * 1024,
			strokeStyle: 'rgba(255, 255, 0, 0.5)',
			opacity: 0.3,
			activePen: 'stroke',
			tempCanvas: null,
			drawCtx: null,
			/** 初始图片 */
			origin_image: null,
			retoucheCount: 0,
			showTemp: true,
			holdOnAltKey: false
		}
	},
	computed: {
		recoveryDisabled() {
			return Boolean(!this.origin_image) || this.retoucheCount === 0;
		},
	},
	onReady: function () {
		console.log('circleImg', circleImg)
		let canvas = document.getElementById("canvas");
		canvas.addEventListener('mousedown', this.ontouchstart);
		canvas.addEventListener('mousemove', this.ontouchmove);
		document.addEventListener('mouseup', this.ontouchend);
		let temp = document.getElementById("temp");
		temp.addEventListener('mousedown', this.ontouchstart);
		temp.addEventListener('mousemove', this.ontouchmove);
		this.addAltandWheelListener();

		this.$nextTick(() => {
			uni.createSelectorQuery().select("#canvas").boundingClientRect(data => {
				ctx = uni.createCanvasContext('canvas');
				this.board = uni.createCanvasContext('board');
				this.marker = uni.createCanvasContext('marker');
				this.cursor = uni.createCanvasContext('cursor');
				tempCtx = uni.createCanvasContext('temp');

				this.initTempCanvas();
				this.clear();
			}).exec()
		})
	},
	onShow: function () {
		console.log('page onShow');
		this.holdOnAltKey = false;
	},
	onHide: function () {
		console.log('page onHide');
		this.holdOnAltKey = false;
	},
	onUnload() {
		let canvas = document.querySelector(".canvas");
		canvas.removeEventListener('mousedown', this.ontouchstart);
		canvas.removeEventListener('mousemove', this.ontouchmove);
		document.removeEventListener('mouseup', this.ontouchend);
		let temp = document.querySelector(".temp");
		temp.removeEventListener('mousedown', this.ontouchstart);
		temp.removeEventListener('mousemove', this.ontouchmove);
		this.removeAltandWheelListener();
		this.clearOriginImages();
	},
	methods: {
		undoDraw: function () {
			DrawTrace.undo();

			console.log('undoDraw traces', DrawTrace.traces);
			this.onDrawTrace(ctx);
		},
		redoDraw: function () {
			DrawTrace.redo();

			console.log('redoDraw traces', DrawTrace.traces);
			this.onDrawTrace(ctx);
		},
		onDrawTrace: async function (ctx) {
			ctx.clearRect(0, 0, this.imageWidth, this.imageHeight);
			ctx.draw(true);
			for (let i = 0; i <= DrawTrace.curIdx; i++) {
				if (DrawTrace.traces[i].operation === 'clear') {
					this.clear();
				} else if (DrawTrace.traces[i].operation === 'stroke') {
					let points = DrawTrace.traces[i].points;
					this.setDrawStyle(ctx, DrawTrace.traces[i].thickness, DrawTrace.traces[i].scale);
					this.drawCurve(ctx, points);
				} else if (DrawTrace.traces[i].operation === 'erase') {
					let points = DrawTrace.traces[i].points;
					this.erase(ctx, points, DrawTrace.traces[i].thickness, DrawTrace.traces[i].scale);
				} else if (DrawTrace.traces[i].operation === 'origin') {
					let originImage = await this.getOriginImage(DrawTrace.traces[i].localStorageIdx);
					this.board.drawImage(originImage, 0, 0, this.imageWidth, this.imageHeight);
					this.board.draw(true);
					this.clear();
				}
			}
		},

		onAltKeyDown: function (e) {
			if (e.keyCode === 18) {
				// console.log('onAltKeyDown holdOnAltKey', this.holdOnAltKey);
				e.preventDefault();
				this.holdOnAltKey = e.repeat;
			}
		},
		onAltKeyUp: function (e) {
			if (e.keyCode === 18) {
				// console.log('onAltKeyUp holdOnAltKey', this.holdOnAltKey);
				e.preventDefault();
				this.holdOnAltKey = false;
			}
		},
		onAltAndWheel: function (e) {
			if (this.holdOnAltKey === true) {
				e.preventDefault();
				// console.log('holdOnAltKey', this.holdOnAltKey)
				// console.log('wheel', e)
				// console.log('e.deltaY', e.deltaY)
				if (e.deltaY < 0) {
					if (this.lineWidth < this.maxLineWidth) {
						this.lineWidth = this.lineWidth + 1;
					}
				} else if (e.deltaY > 0) {
					if (this.lineWidth > this.minLineWidth) {
						this.lineWidth = this.lineWidth - 1;
					}
				}
				this.setCursor();
			}
		},

		addAltandWheelListener: function () {
			document.addEventListener('keydown', this.onAltKeyDown);
			document.addEventListener('keyup', this.onAltKeyUp);
			document.addEventListener('wheel', this.onAltAndWheel, { passive: false })
		},
		removeAltandWheelListener: function () {
			document.removeEventListener('keydown', this.onAltKeyDown)
			document.removeEventListener('keyup', this.onAltKeyUp)
			document.removeEventListener('wheel', this.onAltAndWheel, { passive: false })
		},

		/** 初始化画笔，画一个短线，否则画笔设置不生效 */
		initTempCanvas: function () {
			this.setCursor();
			this.setDrawStyle(tempCtx);
			tempCtx.beginPath();
			tempCtx.moveTo(0, 0);
			tempCtx.lineTo(1, 1);
			tempCtx.stroke();
			tempCtx.closePath();
			tempCtx.clearRect(0, 0, 5, 5);
			tempCtx.draw(true);
		},
		setActiveBtn: function () {
			if (this.activePen === 'stroke') {
				this.strokeBtnStyle.border = `1px solid #007aff`;
				this.strokeBtnStyle.color = `#007aff`;
				this.eraseBtnStyle.border = ``;
				this.eraseBtnStyle.color = ``;
			} else if (this.activePen === 'erase') {
				this.eraseBtnStyle.border = `1px solid #007aff`;
				this.eraseBtnStyle.color = `#007aff`;
				this.strokeBtnStyle.border = ``;
				this.strokeBtnStyle.color = ``;
			}
		},
		setPenStrokeConfirm: function (e) {
			this.activePen = 'stroke';
			this.setCursor();
		},
		setPenStrokeCancel: function (e) {
			this.activePen = 'erase';
			this.setCursor();
		},
		setCursor: async function () {
			// this.setCursorCanvas();
			this.setActiveBtn();
			if (this.activePen === 'stroke') {
				this.drawCursor('circle');
			} else if (this.activePen === 'erase') {
				this.drawCursor('rect');
			}
			const { tempFilePath: cursorUrl } = await uni.canvasToTempFilePath({
				canvasId: 'cursor',
				fileType: 'png'
			});
			const size = Math.floor(this.lineWidth / 2)
			this.containerStyle.cursor = `url(${cursorUrl}) ${size} ${size}, auto`;
		},
		setCursorCanvas: function () {
			this.cursorStyle.width = `${this.lineWidth}px`;
			this.cursorStyle.height = `${this.lineWidth}px`;
		},
		drawCursor: function (type) {
			let ctx = this.cursor;
			// ctx.lineCap = ctx.lineJoin = 'round';
			ctx.lineWidth = 2;
			ctx.clearRect(0, 0, 110, 110);
			if (type === 'circle') {
				ctx.strokeStyle = 'rgba(255, 255, 0, 0.8)';
				ctx.fillStyle = 'rgba(255, 255, 0, 0.8)';
				ctx.beginPath();
				ctx.arc(
					this.lineWidth / 2,
					this.lineWidth / 2,
					this.lineWidth / 2,
					0,
					2 * Math.PI
				);
				ctx.stroke();
				ctx.fill();
				ctx.closePath();
			} else if (type === 'rect') {
				ctx.strokeStyle = 'white';
				ctx.fillStyle = 'white';
				ctx.beginPath();
				ctx.rect(
					2,
					2,
					this.lineWidth,
					this.lineWidth,
				);
				ctx.stroke();
				ctx.closePath();
			}
			ctx.draw(true);
		},

		chooseImage: async function () {
			let that = this;
			this.pointGroup = [];

			// console.log(111111)
			let { tempFilePaths, tempFiles } = await uni.chooseImage({
				count: 1, //默认9
				sizeType: ['original'], //可以指定是原图还是压缩图，默认二者都有
				sourceType: ['album'], //从相册选择
			});

			let filePath = tempFilePaths[0];
			let fileSize = tempFiles[0].size;
			// if (fileSize / 1024  / 1024 > 0.4) {
			// 	// let compressed = await uni.compressImage({
			// 	// 	src: filePath,
			// 	// 	quality: Math.round((4 / (fileSize / 1024 / 1024)) * 100)
			// 	// });
			// 	filePath = compressed.tempFilePath;
			// }



			let image = await uni.getImageInfo({
				src: filePath
			});

			let sys = await uni.getSystemInfoSync();

			that.imageWidth = image.width;
			that.imageHeight = image.height;

			let sysWindowWidth = (sys.windowWidth - 350);
			let sysWindowHeight = (sys.windowHeight - sys.windowTop - 10);
			that.scale = Number(parseInt(sysWindowHeight / that.imageHeight * 10) / 10);
			// let canvasWidth = sysWindowWidth;
			// let canvasHeight = sysWindowWidth / that.imageWidth * that.imageHeight;
			that.canvasStyle.width = `${that.imageWidth}px`;
			that.canvasStyle.height = `${that.imageHeight}px`;
			that.canvasStyle.transform = `translate(-50%, -50%) scale(${that.scale})`;
			ctx.clearRect(0, 0, that.imageWidth, that.imageHeight);
			ctx.draw(true);
			that.board.clearRect(0, 0, that.imageWidth, that.imageHeight);
			that.board.draw(true);

			// 清除一些其他的数据
			this.showTemp = false;
			this.retoucheCount = 0;
			DrawTrace.clear();
			this.clearOriginImages();

			uni.showLoading({
				title: '加载中...'
			});

			setTimeout(async () => {
				let compressedFilePath = await that.compressImage(filePath, fileSize);
				that.origin_image = compressedFilePath;
				let compressFilePath = base64ToImageFile(compressedFilePath);

				that.board.drawImage(compressFilePath, 0, 0, that.imageWidth, that.imageHeight);
				that.board.draw(true);
				uni.hideLoading();
			}, 100);
		},

		ontouchstart: function (e) {
			if (e.button != 0) return;
			this.mouseButtonDown = true;
			this.showTemp = true;
			this.$nextTick(() => {
				this.drawBegin(e);
			});
		},
		ontouchmove: function (e) {
			if (e.button != 0) return;
			if (!this.mouseButtonDown) {
				return;
			}
			throttle(tempCtx.clearRect(0, 0, this.imageWidth, this.imageHeight), 16);
			throttle(this.drawUpdate(e), 16);
		},
		ontouchend: function (e) {
			if (e.button != 0) return;
			if (this.mouseButtonDown) {
				this.mouseButtonDown = false;
				this.drawEnd();
			}
		},

		getCursorPosition: function (e, scale = this.scale) {
			let canvas = document.querySelector(".canvas");
			let canvasPos = canvas.getBoundingClientRect();
			return {
				x: Math.floor((e.clientX - canvasPos.left) / scale),
				y: Math.floor((e.clientY - canvasPos.top) / scale)
			};
		},
		getMidPoint: function (p1, p2) {
			return {
				x: p1.x + (p2.x - p1.x) / 2,
				y: p1.y + (p2.y - p1.y) / 2
			};
		},
		getLastPoints: function (data) {
			const pointGroup = data[data.length - 1];
			return pointGroup.points ?? [];
		},
		getDistance: function (point, start) {
			return Math.sqrt(
				Math.pow(point.x - start.x, 2)
				+ Math.pow(point.y - start.y, 2)
			);
		},

		// 设置离屏画布
		createTempCanvas: function () {
			if (this.tempCanvas) {
				return this.tempCanvas;
			}
			const buffer = document.createElement('canvas');
			buffer.id = generateUUID();
			buffer.style.padding = '0';
			buffer.style.margin = '0';
			buffer.style.border = '0';
			buffer.style.backgroundColor = 'transparent';
			buffer.style.position = 'absolute';
			buffer.style.top = '50%';
			buffer.style.left = '50%';
			buffer.style.width = this.canvasStyle.width;
			buffer.style.height = this.canvasStyle.height;
			buffer.style.transform = this.canvasStyle.transform;
			buffer.style.zIndex = '1000';
			buffer.addEventListener('mousedown', this.ontouchstart);
			buffer.addEventListener('mousemove', this.ontouchmove);
			buffer.addEventListener('mouseup', this.ontouchend);
			document.getElementById('canvas-container').appendChild(buffer);
			return buffer;
		},
		removeTempCanvas: function () {
			// if (!this.tempCanvas) return;

			// 事件更新频率(1/60 = 16ms左右的延迟[60HZ])
			setTimeout(() => {
				tempCtx.clearRect(0, 0, this.imageWidth, this.imageHeight);
				tempCtx.draw(true);
				this.showTemp = false;
			}, 16);
			// const buffer = document.getElementById('temp');
			// buffer.removeEventListener('mousedown', this.ontouchstart);
			// buffer.removeEventListener('mousemove', this.ontouchmove);
			// buffer.removeEventListener('mouseup', this.ontouchend);
			// document.getElementById('canvas-container').removeChild(buffer);
			// this.tempCanvas = null;
		},

		setDrawStyle: function (ctx, lineWidth = this.lineWidth, scale = this.scale) {
			// this.tempCanvas = this.createTempCanvas();
			// this.drawCtx = uni.createCanvasContext(this.tempCanvas.id);
			ctx.lineCap = ctx.lineJoin = 'round';
			ctx.lineWidth = lineWidth / scale;
			ctx.strokeStyle = this.strokeStyle;
			ctx.fillStyle = this.strokeStyle;
		},
		drawBegin: function (e) {
			this.pointGroup.push({
				operation: this.activePen,
				color: this.strokeStyle,
				thickness: this.lineWidth,
				opacity: this.opacity,
				points: [this.getCursorPosition(e)]
			}); // Append point tu current path.

			console.log('pointGroup', this.pointGroup)

			this.setDrawStyle(tempCtx);

			setTimeout(() => {
				this.drawUpdate(e);
			}, 16);
		},
		drawUpdate: function (e) {
			const point = this.getCursorPosition(e),
				lastPoints = this.getLastPoints(this.pointGroup),
				lastPointsLen = lastPoints.length,
				lastPoint = lastPointsLen > 0 && lastPoints[lastPointsLen - 1],
				isPointsTooClose = lastPoint ? this.getDistance(point, lastPoint) <= 5 : false;
			if (!lastPoint || !(lastPoint && isPointsTooClose)) {
				lastPoints.push(point);
				if (this.activePen === 'erase') {
					this.erase(ctx, lastPoints);
				} else {
					this.drawCurve(tempCtx, lastPoints);
				}
			}
		},
		drawCurve: function (ctx, points) {
			ctx.beginPath();
			let p1 = points[0],
				p2 = points[1];
			for (let i = 1, len = points.length; i < len; i++) {
				const midPoint = this.getMidPoint(p1, p2);
				ctx.quadraticCurveTo(p1.x, p1.y, midPoint.x, midPoint.y);
				p1 = points[i];
				p2 = points[i + 1];
			}
			ctx.lineTo(p1.x, p1.y);
			ctx.stroke();
			ctx.closePath();
			ctx.draw(true);
		},
		erase: function (ctx, points, lineWidth = this.lineWidth, scale = this.scale) {
			ctx.beginPath();
			let p1 = points[0];
			for (let i = 1, len = points.length; i < len; i++) {
				p1 = points[i];

				let rectX = p1.x - ((lineWidth / scale) / 2);
				let rectY = p1.y - ((lineWidth / scale) / 2);
				ctx.clearRect(rectX, rectY, lineWidth / scale, lineWidth / scale);
			}

			ctx.closePath();
			ctx.draw(true);
		},
		drawEnd: async function () {
			// 将临时画布的内容移到canvas上
			tempCtx = uni.createCanvasContext('temp');
			// 判断当前trace的步数，将20步之前的保存为一个image
			// 画出20步之前的图像
			// totempfilePath
			// 存储在一个固定的地方,每次重画步骤，都优先画出这个部分
			if (this.activePen === 'erase') {
				DrawTrace.setTraces({
					operation: 'erase',
					thickness: this.lineWidth,
					scale: this.scale,
					points: this.getLastPoints(this.pointGroup)
				});
			} else {
				const { tempFilePath: temp } = await uni.canvasToTempFilePath({
					canvasId: 'temp',
					fileType: 'png'
				});
				ctx.drawImage(temp, 0, 0, this.imageWidth, this.imageHeight);
				ctx.draw(true);
				DrawTrace.setTraces({
					operation: 'stroke',
					thickness: this.lineWidth,
					scale: this.scale,
					points: this.getLastPoints(this.pointGroup)
				});
			}
			// 清除临时画布
			this.removeTempCanvas();
		},

		rendering: function () {

		},

		onClearTrace: function (e) {
			this.clear();
			DrawTrace.setTraces({
				operation: 'clear',
			});
		},

		/** 清空画板涂抹 */
		clear: function () {
			console.log('clear')
			ctx = uni.createCanvasContext('canvas');
			ctx.clearRect(0, 0, this.imageWidth || '200px', this.imageHeight || '200px');
			ctx.draw(true);
		},

		finish: function () {
			uni.canvasToTempFilePath({
				canvasId: 'canvas',
				fileType: 'jpg',
				success: function (res) {
					console.log('-------canvasToTempFilePath------');
					console.log(res);
					console.log(this.index);
					console.log('-------canvasToTempFilePath------');
				}
			})

		},

		retouche: async function () {
			try {

				await this.generateMarker();

				const { tempFilePath: marker } = await uni.canvasToTempFilePath({
					canvasId: 'marker',
					fileType: 'jpg'
				});
				console.log('marker', marker)
				const { tempFilePath: original } = await uni.canvasToTempFilePath({
					canvasId: 'board',
					fileType: 'jpg'
				});
				// console.log('original', original)

				/**
				 * path: /image/people_erase.json
				 * post
				 * body={"user_image": "data:image/<图片的格式>;<图片的base64>", "mask": "data:image/<图片的格式>;<图片的base64>"}
				 * response={"code":1000, "message":"success", "data":{"target_image": "data:image/<图片的格式>;<图片的base64>"}}
				 */
				uni.showLoading({ title: '加载中' });
				const { data } = await uni.request({
					url: '/image/people_erase.json',
					method: 'POST',
					data: JSON.stringify({
						user_image: original,
						mask: marker,
					}),
				});

				const { code, message, data: { target_image } } = data;

				if (code === '1000' && message === 'success') {
					let targetImage = base64ToImageFile(target_image);
					this.board.drawImage(targetImage, 0, 0, this.imageWidth, this.imageHeight);
					this.board.draw(true);
					this.clear();
					this.retoucheCount++;

					let originImages = await this.getOriginImages();
					if (originImages.length === 0) {
						await this.setOriginImages(original);
						await this.setOriginImageTrace();
					}
					await this.setOriginImages(targetImage);
					await this.setOriginImageTrace();

					uni.hideLoading();
				} else {
					uni.hideLoading();
					uni.showModal({
						title: '上传失败',
						content: message,
						showCancel: false,
						success: function (res) {
							if (res.confirm) {
								console.log('用户点击确定');
							} else if (res.cancel) {
								console.log('用户点击取消');
							}
						}
					});
				}
			} catch (error) {
				console.log('error', error);
				uni.hideLoading();
				uni.showModal({
					title: '上传失败',
					content: '未知错误',
					showCancel: false,
					success: function (res) {
					}
				});
			}

		},

		setOriginImageTrace: async function () {
			let originImages = await this.getOriginImages();
			DrawTrace.setTraces({
				operation: 'origin',
				localStorageIdx: originImages.length - 1
			});
			return Promise.resolve();
		},

		/** 存储当前原图 */
		setOriginImages: async function (original) {
			let images = await localForage.getItem('images');
			console.log('images', images)
			let originImages = JSON.parse(images) || [];
			originImages.push({
				base64: original,
			});
			await localForage.setItem('images', JSON.stringify(originImages));
			return Promise.resolve();
		},

		/** 获取单张历史图 */
		getOriginImage: async function (idx) {
			let originImages = await this.getOriginImages();
			return Promise.resolve(originImages[idx]?.base64 || '');
		},

		/** 获取所有历史图 */
		getOriginImages: async function (idx) {
			let images = await localForage.getItem('images');
			return Promise.resolve(JSON.parse(images) || []);
		},

		clearOriginImages: async function () {
			console.log('localForage images clear');
			await localForage.setItem('images', null);
			return Promise.resolve();
		},

		/**  onTestAPI */
		// onTestAPI: async function () {
			// console.log('localForage', localForage);
			// localForage.setItem('images', JSON.stringify({a:'1'}));
			// const Directory = await window.showDirectoryPicker({ id: 'onTestAPI', mode: 'readwrite', startIn: 'pictures' });
			// console.log('Directory', Directory)
			// const fileHandle = await Directory.getFileHandle('test.jpg', { create: true });
			// // 创建要写入的 FileSystemWritableFileStream。
			// const writable = await fileHandle.createWritable();
			// const { tempFilePath: save_image } = await uni.canvasToTempFilePath({
			// 	canvasId: 'board',
			// 	fileType: 'jpg'
			// });
			// // 将文件内容写入流中。
			// await writable.write(base64ToBlob(save_image));
			
			// // 关闭文件并将内容写入磁盘。
			// await writable.close();
		// },

		recovery: async function () {
			try {
				const { tempFilePath: process_image } = await uni.canvasToTempFilePath({
					canvasId: 'board',
					fileType: 'jpg'
				});
				console.log('original', process_image)

				/**
				 * path: /image/main_body_recovery.json
				 * post
				 * 参数：origin_image，原图的base64；process_image，智能修图后的图片的base64
				 * response={"code":1000, "message":"success", "data":{"target_image": "data:image/<图片的格式>;<图片的base64>"}}
				 * 返回值：target_image，最新的图片base64
				 */
				uni.showLoading({ title: '加载中' });
				const { data } = await uni.request({
					url: '/image/main_body_recovery.json',
					method: 'POST',
					data: JSON.stringify({
						origin_image: this.origin_image,
						process_image: process_image,
					}),
				});


				const { code, message, data: { target_image } } = data;

				if (code === '1000' && message === 'success') {
					let targetImage = base64ToImageFile(target_image);
					this.board.drawImage(targetImage, 0, 0, this.imageWidth, this.imageHeight);
					this.board.draw(true);
					this.clear();
					uni.hideLoading();
				} else {
					uni.hideLoading();
					uni.showModal({
						title: '上传失败',
						content: message,
						showCancel: false,
						success: function (res) {
							if (res.confirm) {
								console.log('用户点击确定');
							} else if (res.cancel) {
								console.log('用户点击取消');
							}
						}
					});
				}
			} catch (error) {
				console.log('error', error);
				uni.hideLoading();
				uni.showModal({
					title: '上传失败',
					content: '未知错误',
					showCancel: false,
					success: function (res) {
					}
				});
			}

		},

		generateMarker: async function () {

			return new Promise((resolve) => {
				uni.showLoading({ title: '加载中…' });
				setTimeout(async () => {
					let canvas = document.getElementById("canvas");
					let { data: imageData, width, height } = await uni.canvasGetImageData({
						canvasId: 'canvas',
						x: 0,
						y: 0,
						width: canvas.width,
						height: canvas.height,
					});
					// console.log('imageData', imageData);

					let repaintImageData = imageData;
					for (let i = 0; i < imageData.length; i += 4) {
						let r = imageData[i];
						let g = imageData[i + 1];
						let b = imageData[i + 2];

						if (r !== 0 || g !== 0 || b !== 0) {
							repaintImageData[i] = 255;
							repaintImageData[i + 1] = 255;
							repaintImageData[i + 2] = 255;
							repaintImageData[i + 3] = 255;
						} else {
							repaintImageData[i] = 0;
							repaintImageData[i + 1] = 0;
							repaintImageData[i + 2] = 0;
							repaintImageData[i + 3] = 255;
						}
					}
					// console.log('repaintImageData', repaintImageData);


					// TODO 创建一个不在可视区域内的canvas
					await uni.canvasPutImageData({
						canvasId: 'marker',
						x: 0,
						y: 0,
						width,
						height,
						data: repaintImageData,
					});

					uni.hideLoading();
					resolve();

				}, 100);
			});
		},

		savePicture(base64) {
			let url = base64ToFile(base64);
			var a = document.createElement('a');
			a.href = url;
			a.download = new Date().valueOf() + ".jpg";
			var e = document.createEvent('MouseEvents');
			e.initMouseEvent('click', true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
			a.dispatchEvent(e);
			URL.revokeObjectURL(url);
		},

		download: async function () {
			// console.log('download')
			const { tempFilePath } = await uni.canvasToTempFilePath({
				canvasId: 'board',
				fileType: 'jpg'
			});
			// console.log('tempFilePath', tempFilePath)
			let path = base64ClipPrefix(tempFilePath);
			this.savePicture(path);
			// console.log('path', path)
			// const { savedFilePath } = await uni.saveFile({
			// 	tempFilePath: tempFilePath
			// });
			// console.log('savedFilePath', savedFilePath)
			// uni.saveImageToPhotosAlbum({
			// 	filePath: path,
			// 	success: function () {
			// 		console.log('save success');
			// 	},
			// 	fail: function (err) {
			// 		console.log('save fail', err);
			// 	}
			// });
		},

		downloadMarker: async function () {
			await this.generateMarker();
			const { tempFilePath } = await uni.canvasToTempFilePath({
				canvasId: 'marker',
				fileType: 'jpg'
			});
			let path = base64ClipPrefix(tempFilePath);
			this.savePicture(path);
		},

		compressImage: function (filePath, fileSize) {
			let that = this;

			// 创建canvas
			// const img = new Image();
			// img.src = tempFilePath;

			return new Promise(async (resolve) => {
				that.board.drawImage(filePath, 0, 0, that.imageWidth, that.imageHeight);
				that.board.draw(true);

				console.log('filePath', filePath)
				let quality = 1;
				if (fileSize > that.imageMaxSize) {
					quality = Math.round((that.imageMaxSize / fileSize) * 100) / 100;
					console.log('图片大小: ', fileSize)
					console.log('压缩质量: ', quality)
				}

				setTimeout(async () => {
					const { tempFilePath: compressFilePath } = await uni.canvasToTempFilePath({
						canvasId: 'board',
						fileType: 'jpg',
						quality,
					});
					console.log('compressFilePath', compressFilePath)

					resolve(compressFilePath);
				}, 100);

				// img.onload = async () => {
				// 	// 设置canvas的宽高
				// 	// const ratio = img.width / img.height;
				// 	// canvas.width = 100; // 假设我们想要压缩到100px宽
				// 	// canvas.height = 100 / ratio;
				// 	// 绘制图片

				// };
			})

		},

		lineWidthChange: function (e) {
			console.log('value 发生变化：' + e.detail.value)
			this.lineWidth = e.detail.value;
			this.$nextTick(() => {
				this.setCursor();
			})
		},

		scaleChange: function (e) {
			let that = this;
			console.log('value 发生变化：' + e.detail.value)
			that.scale = e.detail.value / 100;
			that.canvasStyle.transform = `translate(-50%, -50%) scale(${that.scale})`;
			this.$nextTick(() => {
				this.setCursor();
			})
		},


	},
}
</script>

<style>
.menu {
	uni-button {
		margin: 10px auto;

	}
}

.canvas {
	position: absolute;
	width: 100px;
	top: 50%;
	left: 50%;
	/* transform: translate(-50%, -50%) scale(1); */
}

.board {
	position: absolute;
	width: 100px;
	top: 50%;
	left: 50%;
	/* transform: translate(-50%, -50%) scale(1); */
}

.marker {
	position: fixed;
	width: 100px;
	top: 500%;
	left: 500%;
	/* transform: translate(-50%, -50%) scale(1); */
}

.cursor {
	position: fixed;
	/* width: 100px;
	height: 100px; */
	top: 500%;
	left: 500%;
	/* transform: translate(-50%, -50%) scale(1); */
}

.text {
	margin: 15rpx 10rpx;
	padding: 0 20rpx;
	background-color: #ebebeb;
	height: 70rpx;
	line-height: 70rpx;
	text-align: center;
	color: #777;
	font-size: 26rpx;
}

.uni-icon {
	line-height: 1.2;
}
</style>
